package com.azh.server.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.azh.server.tables.TableManager;
import com.azh.server.util.ExceptionUtils;

/**
 * @author zhaozhenhang <zhaozhenhang@kuaishou.com>
 * Created on 2022-05-02
 * Server 启动一个监听端口，当有请求到来时直接把请求丢给一个新线程处理。
 */
public class Server {

    private int port;

    TableManager tableManager;

    public Server(int port, TableManager tableManager) {
        this.port = port;
        this.tableManager = tableManager;
    }

    public void start() {
        ServerSocket ss = null;
        try {
            ss = new ServerSocket(port);
        } catch (IOException e) {
            ExceptionUtils.getMessage(e);
            return;
        }

        ThreadPoolExecutor executor =
                new ThreadPoolExecutor(10, 600, 3L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10000),
                        new ThreadPoolExecutor.CallerRunsPolicy());
        try {
            for (; ; ) {
                Socket socket = ss.accept();
                Runnable worker = new SocketHandeler(socket, tableManager);
                executor.execute(worker);
            }
        } catch (IOException e) {
            ExceptionUtils.getMessage(e);
        }finally {
            try {
                ss.close();
            } catch (IOException e) {
                ExceptionUtils.getMessage(e);
            }
        }
    }
}
